/**
 * 智慧小区管理系统 - 统一权限控制工具函数
 * 
 * 严格按照《智慧社区微服务架构总览.md》的权限体系标准实现
 * 集成权限缓存、监控和性能优化功能
 * 
 * @author Wu.Liang
 * @date 2024-01-01
 * @updated 2025-01-30 - 全面重构，统一权限判断逻辑
 */
import { computed } from 'vue'
import { useUserStore } from '@/store/user'
import { usePermissionStore } from '@/store/permission'
import { ROLE_CODES } from '@/constants/roles'
import type { RouteRecordRaw } from 'vue-router'
import { STATUS } from '@/constants/enums'
import { PermissionCacheManager, usePermissionCache } from './permissionCache'
import { PermissionMonitor, PermissionLogLevel, usePermissionMonitor } from './permissionMonitor'

// 权限类型枚举
export enum PermissionType {
    MENU = 'menu',
    BUTTON = 'button',
    DATA = 'data'
}

// 权限检查结果接口
export interface PermissionResult {
    hasPermission: boolean
    message?: string
    code?: string
    details?: any
}

// 数据权限范围接口
export interface DataScopeResult {
    hasDataScope: boolean
    scope: string[]
    message?: string
}

// 权限检查上下文
export interface PermissionContext {
    module: string
    action: string
    resource?: string | undefined
    userId?: number | undefined
    username?: string | undefined
    userType?: string | undefined
}

/**
 * 统一的权限判断工具类
 */
export class PermissionUtils {
    /**
     * 检查是否为超级管理员（带缓存和监控）
     */
    static isSuperAdmin(context?: PermissionContext): boolean {
        const startTime = Date.now()
        const userStore = useUserStore()
        const result = userStore.userRoles.includes(ROLE_CODES.SUPER_ADMIN)
        
        // 记录权限检查
        if (context) {
            PermissionMonitor.logPermissionCheck(
                context.module,
                context.action,
                'SUPER_ADMIN',
                result,
                context.userId,
                context.username,
                context.userType,
                Date.now() - startTime
            )
        }
        
        return result
    }
    
    /**
     * 检查是否有指定角色（带缓存和监控）
     */
    static hasRole(role: string, context?: PermissionContext): boolean {
        const startTime = Date.now()
        const userStore = useUserStore()
        const result = userStore.userRoles.includes(role)
        
        // 记录权限检查
        if (context) {
            PermissionMonitor.logPermissionCheck(
                context.module,
                context.action,
                `ROLE:${role}`,
                result,
                context.userId,
                context.username,
                context.userType,
                Date.now() - startTime
            )
        }
        
        return result
    }
    
    /**
     * 检查是否有指定权限（带缓存和监控）
     */
    static hasPermission(permission: string, context?: PermissionContext): boolean {
        const startTime = Date.now()
        const userStore = useUserStore()
        
        // 超级管理员拥有所有权限
        if (PermissionUtils.isSuperAdmin(context)) {
            return true
        }
        
        const result = userStore.userPermissions.includes(permission)
        
        // 记录权限检查
        if (context) {
            PermissionMonitor.logPermissionCheck(
                context.module,
                context.action,
                permission,
                result,
                context.userId,
                context.username,
                context.userType,
                Date.now() - startTime
            )
        }
        
        return result
    }
    
    /**
     * 检查是否有数据权限（带缓存和监控）
     */
    static hasDataScope(dataScope: string, context?: PermissionContext): boolean {
        const startTime = Date.now()
        const userStore = useUserStore()
        
        // 超级管理员拥有所有数据权限
        if (PermissionUtils.isSuperAdmin(context)) {
            return true
        }
        
        const result = userStore.userDataScope.includes(dataScope)
        
        // 记录权限检查
        if (context) {
            PermissionMonitor.logPermissionCheck(
                context.module,
                context.action,
                `DATA_SCOPE:${dataScope}`,
                result,
                context.userId,
                context.username,
                context.userType,
                Date.now() - startTime
            )
        }
        
        return result
    }
    
    /**
     * 检查用户是否有关联物业公司（带缓存和监控）
     */
    static async hasPropertyCompany(context?: PermissionContext): Promise<boolean> {
        const startTime = Date.now()
        
        try {
            // 使用权限缓存管理器
            const hasCompany = await PermissionCacheManager.checkAndUpdateCompanyInfo()
            
            // 记录权限检查
            if (context) {
                PermissionMonitor.logPermissionCheck(
                    context.module,
                    context.action,
                    'PROPERTY_COMPANY',
                    hasCompany,
                    context.userId,
                    context.username,
                    context.userType,
                    Date.now() - startTime
                )
            }
            
            return hasCompany
        } catch (error) {
            // 记录权限错误
            if (context) {
                PermissionMonitor.logPermissionError(
                    context.module,
                    context.action,
                    error instanceof Error ? error : '检查物业公司权限失败',
                    { error }
                )
            }
            
            return false
        }
    }
    
    /**
     * 获取用户数据权限范围（带缓存）
     */
    static getDataScope(context?: PermissionContext): DataScopeResult {
        const startTime = Date.now()
        
        if (PermissionUtils.isSuperAdmin(context)) {
            return {
                hasDataScope: true,
                scope: ['ALL']
            }
        }
        
        const userStore = useUserStore()
        const userDataScope = userStore.userDataScope || []
        const result: DataScopeResult = {
            hasDataScope: userDataScope.length > 0,
            scope: userDataScope
        }
        
        // 记录权限检查
        if (context) {
            PermissionMonitor.logPermissionCheck(
                context.module,
                context.action,
                'DATA_SCOPE',
                result.hasDataScope,
                context.userId,
                context.username,
                context.userType,
                Date.now() - startTime
            )
        }
        
        return result
    }
    
    /**
     * 检查操作权限（统一入口）
     */
    static async checkOperationPermission(
        operation: string,
        resource?: string,
        context?: PermissionContext
    ): Promise<PermissionResult> {
        const startTime = Date.now()
        
        try {
            // 构建权限上下文
            const permissionContext: PermissionContext = {
                module: context?.module || 'unknown',
                action: context?.action || operation,
                resource,
                userId: context?.userId,
                username: context?.username,
                userType: context?.userType
            }
            
            // 超级管理员拥有所有权限
            if (PermissionUtils.isSuperAdmin(permissionContext)) {
                return {
                    hasPermission: true,
                    message: '超级管理员权限',
                    code: 'SUPER_ADMIN'
                }
            }
            
            // 检查物业公司权限
            const hasPropertyCompany = await PermissionUtils.hasPropertyCompany(permissionContext)
            if (hasPropertyCompany) {
                return {
                    hasPermission: true,
                    message: '物业公司权限',
                    code: 'PROPERTY_COMPANY'
                }
            }
            
            // 检查具体权限
            const hasPermission = PermissionUtils.hasPermission(operation, permissionContext)
            
            return {
                hasPermission,
                message: hasPermission ? '权限检查通过' : '权限不足',
                code: hasPermission ? 'SUCCESS' : 'PERMISSION_DENIED'
            }
        } catch (error) {
            // 记录权限错误
            if (context) {
                PermissionMonitor.logPermissionError(
                    context.module,
                    context.action,
                    error instanceof Error ? error : '权限检查失败',
                    { operation, resource, error }
                )
            }
            
            return {
                hasPermission: false,
                message: '权限检查异常',
                code: 'ERROR',
                details: error
            }
        }
    }
}

/**
 * 权限计算属性管理器
 * 使用computed属性缓存权限判断结果，避免重复计算
 */
export class PermissionComputedManager {
    private static computedCache = new Map<string, any>()
    
    /**
     * 获取超级管理员状态（计算属性）
     */
    static get isSuperAdmin() {
        const key = 'isSuperAdmin'
        if (!this.computedCache.has(key)) {
            this.computedCache.set(key, computed(() => {
                return PermissionUtils.isSuperAdmin({
                    module: 'computed',
                    action: 'isSuperAdmin'
                })
            }))
        }
        return this.computedCache.get(key)
    }
    
    /**
     * 获取物业公司权限状态（计算属性）
     */
    static get hasPropertyCompany() {
        const key = 'hasPropertyCompany'
        if (!this.computedCache.has(key)) {
            this.computedCache.set(key, computed(async () => {
                return await PermissionUtils.hasPropertyCompany({
                    module: 'computed',
                    action: 'hasPropertyCompany'
                })
            }))
        }
        return this.computedCache.get(key)
    }
    
    /**
     * 获取操作权限状态（计算属性）
     */
    static getOperationPermission(operation: string, resource?: string) {
        const key = `operation_${operation}_${resource || 'default'}`
        if (!this.computedCache.has(key)) {
            this.computedCache.set(key, computed(async () => {
                return await PermissionUtils.checkOperationPermission(operation, resource, {
                    module: 'computed',
                    action: operation,
                    resource
                })
            }))
        }
        return this.computedCache.get(key)
    }
    
    /**
     * 清除计算属性缓存
     */
    static clearComputedCache(): void {
        this.computedCache.clear()
        console.log('[权限计算属性] 缓存已清除')
    }
}

// 导出权限检查函数（保持向后兼容）
export function checkRole(role: string): PermissionResult {
    const userStore = useUserStore()

    // 超级管理员拥有所有角色
    if (userStore.userRoles.includes(ROLE_CODES.SUPER_ADMIN)) {
        return { hasPermission: true }
    }

    // 检查用户是否登录
    if (!userStore.isLogged) {
        return {
            hasPermission: false,
            message: '用户未登录',
            code: 'NOT_LOGGED_IN'
        }
    }

    // 检查角色
    const hasRole = userStore.userRoles.includes(role)

    return {
        hasPermission: hasRole,
        message: hasRole ? '角色检查通过' : '角色权限不足',
        code: hasRole ? 'SUCCESS' : 'ROLE_DENIED'
    }
}

export function checkPermission(permission: string): PermissionResult {
    const userStore = useUserStore()

    // 超级管理员拥有所有权限
    if (userStore.userRoles.includes(ROLE_CODES.SUPER_ADMIN)) {
        return { hasPermission: true }
    }

    // 检查用户是否登录
    if (!userStore.isLogged) {
        return {
            hasPermission: false,
            message: '用户未登录',
            code: 'NOT_LOGGED_IN'
        }
    }

    // 检查权限
    const hasPermission = userStore.userPermissions.includes(permission)

    return {
        hasPermission,
        message: hasPermission ? '权限检查通过' : '权限不足',
        code: hasPermission ? 'SUCCESS' : 'PERMISSION_DENIED'
    }
}

export function checkMenuPermission(menuPath: string): boolean {
    const userStore = useUserStore()
    return userStore.userPermissions.includes(menuPath)
}

export async function generateDynamicRoutes(userRoles: string[]): Promise<RouteRecordRaw[]> {
    const permissionStore = usePermissionStore()
    // 暂时返回空数组，后续根据实际需求实现
    return []
}

export function isLoggedIn(): boolean {
    const userStore = useUserStore()
    return userStore.isLogged
}

export function getUserInfo() {
    const userStore = useUserStore()
    return userStore.userInfo
}

export function getUserRoles(): string[] {
    const userStore = useUserStore()
    return userStore.userRoles
}

export function getUserPermissions(): string[] {
    const userStore = useUserStore()
    return userStore.userPermissions
}

export function getUserDataScope(): string[] {
    const userStore = useUserStore()
    return userStore.userDataScope || []
}

export function getUserPropertyCompanyId(): number | undefined {
    const userStore = useUserStore()
    const id = userStore.userInfo?.propertyCompanyId
    if (typeof id === 'string') {
        const num = Number(id)
        return isNaN(num) ? undefined : num
    }
    return typeof id === 'number' ? id : undefined
}

export function isAdminRole(roleCode: string): boolean {
    return [
        ROLE_CODES.SUPER_ADMIN,
        ROLE_CODES.ADMIN,
        ROLE_CODES.PROPERTY_ADMIN,
        ROLE_CODES.COMMUNITY_ADMIN
    ].includes(roleCode as any)
}

export function isSuperAdminRole(roleCode: string): boolean {
    return roleCode === ROLE_CODES.SUPER_ADMIN
}

export function isSuperAdminOrPropertyCompany(): boolean {
    const userStore = useUserStore()
    return PermissionUtils.isSuperAdmin() || userStore.hasCompany === true
}

export function isRegionManagementRole(roleCode: string): boolean {
    return [
        ROLE_CODES.SUPER_ADMIN,
        ROLE_CODES.ADMIN,
        ROLE_CODES.COMMUNITY_ADMIN
    ].includes(roleCode as any)
}

export function isPropertyManagementRole(roleCode: string): boolean {
    return [
        ROLE_CODES.SUPER_ADMIN,
        ROLE_CODES.PROPERTY_ADMIN
    ].includes(roleCode as any)
}

export function isSecurityManagementRole(roleCode: string): boolean {
    return [
        ROLE_CODES.SUPER_ADMIN,
        ROLE_CODES.SECURITY_GUARD
    ].includes(roleCode as any)
}

export function isManagementRole(roleCode: string): boolean {
    return [
        ROLE_CODES.SUPER_ADMIN,
        ROLE_CODES.ADMIN,
        ROLE_CODES.PROPERTY_ADMIN,
        ROLE_CODES.COMMUNITY_ADMIN,
        ROLE_CODES.SECURITY_GUARD
    ].includes(roleCode as any)
}

export function isRoleInGroup(roleCode: string, roleGroup: string[]): boolean {
    return roleGroup.includes(roleCode)
}

export function getRoleName(roleCode: string): string {
    const roleNameMap: Record<string, string> = {
        [ROLE_CODES.SUPER_ADMIN]: '超级管理员',
        [ROLE_CODES.ADMIN]: '系统管理员',
        [ROLE_CODES.PROPERTY_ADMIN]: '物业管理员',
        [ROLE_CODES.COMMUNITY_ADMIN]: '社区管理员',
        [ROLE_CODES.SECURITY_GUARD]: '安保人员',
        [ROLE_CODES.USER]: '普通用户'
    }
    return roleNameMap[roleCode] || '未知角色'
}

export function getRolePermissionPrefix(roleCode: string): string {
    const prefixMap: Record<string, string> = {
        [ROLE_CODES.SUPER_ADMIN]: 'system',
        [ROLE_CODES.ADMIN]: 'admin',
        [ROLE_CODES.PROPERTY_ADMIN]: 'property',
        [ROLE_CODES.COMMUNITY_ADMIN]: 'community',
        [ROLE_CODES.SECURITY_GUARD]: 'security',
        [ROLE_CODES.USER]: 'user'
    }
    return prefixMap[roleCode] || 'unknown'
}

export function hasMenuPermission(menuCode: string): PermissionResult {
    const userStore = useUserStore()

    // 超级管理员拥有所有菜单权限
    if (userStore.userRoles.includes(ROLE_CODES.SUPER_ADMIN)) {
        return { hasPermission: true }
    }

    // 检查用户是否登录
    if (!userStore.isLogged) {
        return {
            hasPermission: false,
            message: '用户未登录',
            code: 'NOT_LOGGED_IN'
        }
    }

    // 检查菜单权限
    const hasPermission = userStore.userPermissions.includes(menuCode)

    return {
        hasPermission,
        message: hasPermission ? '菜单权限检查通过' : '菜单权限不足',
        code: hasPermission ? 'SUCCESS' : 'MENU_DENIED'
    }
}

export function checkPropertyInfoPermission(action: 'view' | 'update' | 'delete'): PermissionResult {
    const userStore = useUserStore()

    // 超级管理员拥有所有权限
    if (userStore.userRoles.includes(ROLE_CODES.SUPER_ADMIN)) {
        return { hasPermission: true }
    }

    // 检查用户是否登录
    if (!userStore.isLogged) {
        return {
            hasPermission: false,
            message: '用户未登录',
            code: 'NOT_LOGGED_IN'
        }
    }

    // 检查物业公司权限
    const hasPropertyCompany = userStore.hasCompany === true
    if (!hasPropertyCompany) {
        return {
            hasPermission: false,
            message: '未关联物业公司',
            code: 'NO_PROPERTY_COMPANY'
        }
    }

    // 根据操作类型检查具体权限
    const permissionMap = {
        view: 'property:info:view',
        update: 'property:info:update',
        delete: 'property:info:delete'
    }

    const requiredPermission = permissionMap[action]
    const hasPermission = userStore.userPermissions.includes(requiredPermission)

    return {
        hasPermission,
        message: hasPermission ? '物业信息权限检查通过' : '物业信息权限不足',
        code: hasPermission ? 'SUCCESS' : 'PROPERTY_INFO_DENIED'
    }
}

// 导出权限工具函数（保持向后兼容）
export const isSuperAdmin = () => PermissionUtils.isSuperAdmin()
export const hasRole = (role: string) => PermissionUtils.hasRole(role)
export const hasPermission = (permission: string) => PermissionUtils.hasPermission(permission)
export const hasDataScope = (dataScope: string) => PermissionUtils.hasDataScope(dataScope)
export const hasPropertyCompany = () => PermissionUtils.hasPropertyCompany()
export const getDataScope = () => PermissionUtils.getDataScope()

// 导出权限缓存和监控
export { usePermissionCache, usePermissionMonitor }

/**
 * 数据权限范围工具函数
 * 用于将数据权限范围转换为用户友好的文本、描述和标签类型
 */

/**
 * 获取数据权限范围文本
 * @param dataScope 数据权限范围数组
 * @returns 用户友好的权限范围文本
 */
export function getDataScopeText(dataScope: string[] = []): string {
  if (!dataScope || dataScope.length === 0) {
    return '无数据权限'
  }
  
  // 超级管理员拥有所有权限
  if (PermissionUtils.isSuperAdmin()) {
    return '全部数据'
  }
  
  // 物业公司人员
  if (dataScope.includes('PROPERTY_COMPANY')) {
    return '物业公司数据'
  }
  
  // 社区级别权限
  if (dataScope.includes('COMMUNITY')) {
    return '社区数据'
  }
  
  // 楼栋级别权限
  if (dataScope.includes('BUILDING')) {
    return '楼栋数据'
  }
  
  // 单元级别权限
  if (dataScope.includes('UNIT')) {
    return '单元数据'
  }
  
  // 房户级别权限
  if (dataScope.includes('HOUSEHOLD')) {
    return '房户数据'
  }
  
  // 自定义范围
  if (dataScope.length > 0) {
    return `自定义范围 (${dataScope.length}项)`
  }
  
  return '无数据权限'
}

/**
 * 获取数据权限范围描述
 * @param dataScope 数据权限范围数组
 * @returns 详细的权限范围描述
 */
export function getDataScopeDescription(dataScope: string[] = []): string {
  if (!dataScope || dataScope.length === 0) {
    return '您当前没有任何数据访问权限'
  }
  
  // 超级管理员
  if (PermissionUtils.isSuperAdmin()) {
    return '您拥有系统的全部数据访问权限，可以查看和管理所有数据'
  }
  
  // 物业公司人员
  if (dataScope.includes('PROPERTY_COMPANY')) {
    return '您拥有物业公司级别的数据访问权限，可以查看和管理关联物业公司的所有数据'
  }
  
  // 社区级别权限
  if (dataScope.includes('COMMUNITY')) {
    return '您拥有社区级别的数据访问权限，可以查看和管理指定社区的数据'
  }
  
  // 楼栋级别权限
  if (dataScope.includes('BUILDING')) {
    return '您拥有楼栋级别的数据访问权限，可以查看和管理指定楼栋的数据'
  }
  
  // 单元级别权限
  if (dataScope.includes('UNIT')) {
    return '您拥有单元级别的数据访问权限，可以查看和管理指定单元的数据'
  }
  
  // 房户级别权限
  if (dataScope.includes('HOUSEHOLD')) {
    return '您拥有房户级别的数据访问权限，可以查看和管理指定房户的数据'
  }
  
  // 自定义范围
  if (dataScope.length > 0) {
    return `您拥有自定义数据访问权限，可以查看和管理 ${dataScope.length} 个指定范围的数据`
  }
  
  return '您当前没有任何数据访问权限'
}

/**
 * 获取数据权限范围标签类型
 * @param dataScope 数据权限范围数组
 * @returns Element Plus标签类型
 */
export function getDataScopeTagType(dataScope: string[] = []): 'success' | 'warning' | 'danger' | 'info' {
  if (!dataScope || dataScope.length === 0) {
    return 'danger'
  }
  
  // 超级管理员
  if (PermissionUtils.isSuperAdmin()) {
    return 'success'
  }
  
  // 物业公司人员
  if (dataScope.includes('PROPERTY_COMPANY')) {
    return 'success'
  }
  
  // 社区级别权限
  if (dataScope.includes('COMMUNITY')) {
    return 'warning'
  }
  
  // 楼栋级别权限
  if (dataScope.includes('BUILDING')) {
    return 'warning'
  }
  
  // 单元级别权限
  if (dataScope.includes('UNIT')) {
    return 'info'
  }
  
  // 房户级别权限
  if (dataScope.includes('HOUSEHOLD')) {
    return 'info'
  }
  
  // 自定义范围
  if (dataScope.length > 0) {
    return 'info'
  }
  
  return 'danger'
}

/**
 * 获取数据权限范围图标
 * @param dataScope 数据权限范围数组
 * @returns Element Plus图标名称
 */
export function getDataScopeIcon(dataScope: string[] = []): string {
  if (!dataScope || dataScope.length === 0) {
    return 'Lock'
  }
  
  // 超级管理员
  if (PermissionUtils.isSuperAdmin()) {
    return 'Star'
  }
  
  // 物业公司人员
  if (dataScope.includes('PROPERTY_COMPANY')) {
    return 'OfficeBuilding'
  }
  
  // 社区级别权限
  if (dataScope.includes('COMMUNITY')) {
    return 'House'
  }
  
  // 楼栋级别权限
  if (dataScope.includes('BUILDING')) {
    return 'OfficeBuilding'
  }
  
  // 单元级别权限
  if (dataScope.includes('UNIT')) {
    return 'Grid'
  }
  
  // 房户级别权限
  if (dataScope.includes('HOUSEHOLD')) {
    return 'User'
  }
  
  // 自定义范围
  if (dataScope.length > 0) {
    return 'Setting'
  }
  
  return 'Lock'
}

/**
 * 检查是否有指定数据权限范围
 * @param requiredScope 需要的权限范围
 * @param userDataScope 用户的数据权限范围
 * @returns 是否有权限
 */
export function hasDataScopePermission(requiredScope: string, userDataScope: string[] = []): boolean {
  if (!userDataScope || userDataScope.length === 0) {
    return false
  }
  
  // 超级管理员拥有所有权限
  if (PermissionUtils.isSuperAdmin()) {
    return true
  }
  
  // 检查是否包含所需权限
  return userDataScope.includes(requiredScope)
}

/**
 * 获取数据权限范围层级
 * @param dataScope 数据权限范围数组
 * @returns 权限层级 (0-无权限, 1-房户级, 2-单元级, 3-楼栋级, 4-社区级, 5-物业公司级, 6-超级管理员)
 */
export function getDataScopeLevel(dataScope: string[] = []): number {
  if (!dataScope || dataScope.length === 0) {
    return 0
  }
  
  // 超级管理员
  if (PermissionUtils.isSuperAdmin()) {
    return 6
  }
  
  // 物业公司人员
  if (dataScope.includes('PROPERTY_COMPANY')) {
    return 5
  }
  
  // 社区级别权限
  if (dataScope.includes('COMMUNITY')) {
    return 4
  }
  
  // 楼栋级别权限
  if (dataScope.includes('BUILDING')) {
    return 3
  }
  
  // 单元级别权限
  if (dataScope.includes('UNIT')) {
    return 2
  }
  
  // 房户级别权限
  if (dataScope.includes('HOUSEHOLD')) {
    return 1
  }
  
  return 0
}

/**
 * 格式化数据权限范围显示
 * @param dataScope 数据权限范围数组
 * @param format 格式化类型 ('text' | 'description' | 'tag' | 'icon' | 'level')
 * @returns 格式化后的结果
 */
export function formatDataScope(
  dataScope: string[] = [], 
  format: 'text' | 'description' | 'tag' | 'icon' | 'level' = 'text'
): string | number {
  switch (format) {
    case 'text':
      return getDataScopeText(dataScope)
    case 'description':
      return getDataScopeDescription(dataScope)
    case 'tag':
      return getDataScopeTagType(dataScope)
    case 'icon':
      return getDataScopeIcon(dataScope)
    case 'level':
      return getDataScopeLevel(dataScope)
    default:
      return getDataScopeText(dataScope)
  }
}
